<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <title>test</title>
  <link rel="stylesheet" href="../layui/css/layui.css">
  <style>
    .layui-table{
      border:#000 3px solid;
    }
   .layui-table td{
    width: 48px;
    height: 48px;
    padding: 0px;
    font-size: 30px;
    text-align: center;
    /* color:red; */
    background-color:#d2d2d2;
    border:#999 1px solid; 
   } 
   .layui-anim {
    width: 65px;
    height: 65px;
    line-height: 65px;
    margin: 0 auto 10px;
    text-align: center;
    background-color: #16baaa;
    cursor: pointer;
    color: #fff;
    border-radius: 50%;
    user-select: none;
}
#oper button{
  width: 200px;
  margin-top:10px ;
}
#oper .layui-form-switch {
    margin-top: 10px;
    margin-left: 10px;
}
.layui-form-switch {
    height: 40px;
    line-height: 35px;
    min-width: 50px;
    width: 150px;
    padding: 0 5px;
    margin-top: 8px;
    border: 1px solid #d2d2d2;
    border-radius: 20px;
}
.layui-form-switch>div{
  font-size: 14px;
}
.layui-form-switch>i {
    top:7px;
    width: 23px;
    height: 23px;
}
.layui-form-onswitch>i {
    left: 95%;
    margin-left: -21px;
    background-color: #fff;
}
.border_right{
  border-right:#999 2px solid; 
}
.border_bottom{
  border-bottom:#999 2px solid; 
}
.layui-input, .layui-textarea {
    height: 100%;
    border: 0px;
}
#sudoku_layer td{
    width: 30px;
    height: 30px;
    padding: 0px;
    font-size: 18px;
    text-align: center;
    border:#999 2px solid; 
    /* background-color:#d2d2d2;
    border:#999 px solid;  */
   } 
  </style>
</head>
<body>
<div class="layui-container layui-form layui-form-pane">
  <div class="layui-row" style="margin-top:50px ;">
    <div class="layui-col-xs8 layui-col-lg-offset2" style="color: #000;">
      <div class="grid-demo" style="border:#999 1px solid;">
        <div class="layui-row " style="margin-top: 20px;text-align:center ;" >
          <div id="sudoku_level_btn" class="layui-col-xs8" style="margin-left:20px ;">
            <input type="hidden" id="sudoku_level" value="1">
            <button type="button" class="layui-btn layui-bg-blue layui-btn-radius" lay-on='sudoku_primary'>简单</button>
            <button type="button" class="layui-btn layui-bg-orange" lay-on='sudoku_intermediate'>中等</button>
            <button type="button" class="layui-btn layui-bg-red" lay-on='sudoku_senior'>困难</button>
            <button type="button" class="layui-btn layui-bg-purple" lay-on='sudoku_hardcore'>骨灰</button>
          </div>
          <div class="layui-col-xs3" style="font-size: large; text-align: justify; ">
            <div class="layui-row ">
              <div class="layui-col-xs4" style="display: flex;">
                <div>错误:</div>
                <div id="sudoku_error_num" style="color:red ;font-size: 20px;margin-left:5px ;">0</div>
              </div>
              <div class="layui-col-xs8" style="display: flex;">
                <div >时间:</div>
                <div id="timer" style="color:chartreuse;font-size: 20px;"></div>
              </div>
            </div>
          </div>
        </div>
        <div class="layui-row " style="margin-top: 0px;margin-bottom: 50px;">
          <div class="layui-col-xs8" style="margin-left:20px ;">
            <table class="layui-table" id="sudoku">
            </table>
          </div>
          <div class="layui-col-xs3">
            <div class="layui-row"  id="oper">
              <button type="button" class="layui-btn layui-bg-blue" style="margin-left:10px ;" lay-on='revoke_sudoku'>撤销</button>
              <!-- <button type="button" class="layui-btn layui-bg-blue" >重做</button>
              <button type="button" class="layui-btn layui-bg-blue" >提示</button> -->
              <button type="button" class="layui-btn layui-bg-blue " lay-on='reset_sudoku'>重置</button>
              <input type="checkbox" id="auto_check" style="margin-top:20px ;"name="CCC" title="自动检查开启|自动检查关闭" lay-skin="switch" checked>
              <input type="checkbox" id="auto_special" style="margin-top:20px ;" name="CCC" title="强调数字开启|强调数字关闭" lay-skin="switch" checked>
              <input type="checkbox" id="auto_area" style="margin-top:20px ;"name="CCC" title="强调区域开启|强调区域关闭" lay-skin="switch" >
            </div>
          </div> 
        </div>
        <div class="layui-row"></div>
      </div>
    </div>
  </div>
</div>

<!-- body 末尾处引入 layui -->
<script src="../layui/layui.js"></script>
<script src="./sudoku.js"></script>
<script>
layui.use(function(){
  let $ = layui.$;
  let table = layui.table; //表格
  let util = layui.util;
  let select_cell_num=[];//用来存入用户输入的数字
  let cell_all_num=[];//用来存储单元格的所有数据
  let default_data=''; //用来存入默认的数字
  let error_num=0;//错误数
  //默认的文字颜色红色，背景黑色
  //默认初始化显示等级
  get_sudoku_info($('#sudoku_level').val());
  setInterval(f, 1000);	
  //获取数独数据
  function get_sudoku_info(level){
    console.log(level);
    MODULE_PATH="http://8.141.3.178:8802/api/index/index?app=i10100joybb"
    $.ajax({
            url: MODULE_PATH,
            data: {'service':'getSudoku','level':level},
            dataType: 'json',
            type: 'post',
            async:false,
            success: function(result) {
                console.log(result)
                if (result.code==0) {
                  default_data=result.data.content;
                  init_sudoku(result.data.content)
                }
            }
        })
  }

  //初始化数独表结构
  function init_sudoku(data){

    //data='[1, 4, 7, 6, 2, 5, 3, 8, 9, 2, 9, 6, 1, 8, 3, 7, 4, 5, 8, 3, 5, 4, 7, 9, 1, 6, 2, 9, 2, 1, 3, 6, 8, 5, 7, 4, 4, 6, 3, 5, 1, 7, 2, 9, 8, 7, 5, 8, 2, 9, 4, 6, 3, 1, 6, 7, 2, 9, 4, 1, 8, 5, 3, 5, 1, 4, 8, 3, 6, 9, 2, 7, 3, 8, 0, 0, 0, 2, 4, 1, 6]';
    html='';
    var data = JSON.parse(data);
    //把单元格数据存储起来
    cell_all_num=data;
    for(i=1;i<10;i++){
      html+="<tr>"; 
      for(j=1;j<10;j++){
        str_boder=str_begin=str_end=str_middle='';
        if(i%3==0){
          str_boder='border-bottom:#999 2px solid;';
        }
        if(j%3==0){
          str_boder+='border-right:#999 2px solid;';
        }
        index=(i-1)*9+j;
        id='cell_'+index;
        //ccontent 是需要添充内容的input的id
        //cctip 是用户标记内容的input的id
        if(data[index-1]==0){
          str_boder+='position: relative;';
          str_middle="<input type='text' lay-verify='required' name='ccontent' lay-blur='checkUsername' id='ccontent_"+index+"' style='text-align:center;padding-left:0px;' class='layui-input' lay-on='showlayer' >";
          str_middle+="<input id='ctip_"+index+"' name='ctip' style='position: absolute; left:5px; top:-10px; width:40px;height:15px;font-size:20px;color:#16b777; border:0px;background-color: transparent;'  type='text' lay-on='showlayer'>"; 
        }else{
          str_middle=data[index-1];
        }
        str_begin="<td id='"+id+"' style='"+str_boder+"'  lay-on='selectedCell' >";
        str_end="</td>";

        html+=str_begin+str_middle+str_end;
      }
      html+="</tr>"; 
    }
    //console.log(html)
    $('#sudoku').empty();
    $('#sudoku').append(html);
  }
  //监听手动添加数据事件
  $("#sudoku input[name=ccontent] ").bind('change', function(event) {
      // console.log('val:'+$(this).val());
      // console.log('old val:'+$(this).data("old-value"));
      // console.log('id:'+$(this).attr('id'));
      //debugger
      add_cell_data($(this).val(),$(this).attr('id'),1)
  })
  //给单元格添加数字 type(1:手动输入|2:鼠标点击)
  function add_cell_data(cell_num,current_id,type){

    //判断是否是提示框(提示框和输入框的区别)
    if($('#'+current_id).attr('name')=='ctip'){
      //把原来的值和新选中的值都添入输入框中
      $('#'+current_id).val($('#'+current_id).val()+cell_num)
      return '';
    }
    //得到输入框中原来值
    source_num=$('#'+current_id).val();
    //把选中的值添加到输入框中(和弹出层选中的不一样)
    console.log('------change value------')
    $('#'+current_id).val(cell_num)
    console.log($('#'+current_id).val())
    console.log('------change value------')
    current_num=cell_num;
    arr_id=current_id.split('_')
    need_check=get_relate_data(arr_id[1]);

    if(type==1){
      if(arr_id[1]!=''&&current_num!=''&&arr_id[1]!=undefined&&current_num!=undefined){
        select_cell_num.push(arr_id[1]);        
      }
    }else if(type==2) {
      //把添入输入框的值，存入列表中(原来输入框中没有值，才会给长度添加1)
      if((source_num==''||source_num==undefined)&& arr_id[1]!=''&&current_num!=''&&arr_id[1]!=undefined&&current_num!=undefined){
        select_cell_num.push(arr_id[1]);        
      }
    }else{
      console.log('type error;');
      return;
    }
    cell_all_num[arr_id[1]-1]=current_num

    if ($("#auto_check").is(':checked')) {
      //选择完数字，再判断是否有重复
      select_cell(current_num,arr_id[1]);
      //console.log(need_check)
      //当前选中的数字，默认是整个数独中存在数值的，如果有重复，就显示红色
      is_repeat='#FFFF00';
      //判断行，列，宫中是否有重复
      for(i=0;i<need_check.length;i++){
        //需要去掉本身，先找默认生成的，再找用户输入的
        value=$('#cell_'+need_check[i]).text()
        if(value==''){
          value=$('#cell_'+need_check[i]+' input[name=ccontent]').val()
        }
        if(value==cell_num){
          error_num++
          $('#sudoku_error_num').html(error_num) 
          is_repeat='#FF0000';
          break;
        }
        console.log(value)
      }
      $('#'+current_id).css('background-color',is_repeat);
    }
    console.log('------finish------')
    //判断是否输入完成
    if(get_add_finish()){
      if(check_grid()){
        //为了防止先弹出成功，单元格再显示数字，所以所了延迟
        setTimeout(function(){
          alert('成功');
        },500)
      }
    }
    console.log('------data legnth end------------');
    layer.closeAll(); // 关闭所有类型的层
  }


  //判断数据是否添完
  function get_add_finish(){
    console.log('-----get_add_finish------')
    is_finish=true;
    console.log(cell_all_num)
   for(i=0;i<81;i++){
    if(cell_all_num[i]==0||cell_all_num[i]==''){
      is_finish=false;
      break
    }
   }
   console.log('-----get_add_finish------:'+is_finish) 
   return is_finish;
  }


   
 //点击弹出数字层
util.on('lay-on', {
    //选择弹出层的数字，添充到选择区
    'choose_sudoku_num': function(othis){
      add_cell_data($(othis).text(),$('#layer_id').val(),2); 
    },
     //选中数字，所有当前值都变色
    'selectedCell': function(othis){
      //debugger;
      console.log('selectedCell')
      console.log($(this).attr('id'))
      num=$(othis).text();
      if(num==''){
        num=$(othis).find('input[name=ccontent]').val();
      }
      //因为可能只获取焦点，还没有输入值
      if(num==''){
        return true;
      }
      //如果选中数据，判断是否需要自动验证
      arr_id=$(this).attr('id').split('_')
      select_cell(num,arr_id[1]);
    },
    //撤消，返回上一步
    'revoke_sudoku': function(othis){
      cell=select_cell_num.pop();
      $('#ccontent_'+cell).val('');
      //如果撤消，把背景颜色也清空
      for(i=1;i<82;i++){
        //判断输入控件是否存在
        if($('#ccontent_'+i).length>0){
          $('#ccontent_'+i).css('background-color','');
        }else{
          $('#cell_'+i).css('background-color','');
        }
      }

    },
    //重置
    'reset_sudoku': function(othis){
      init_sudoku(default_data)
    },
    //删除当前单元格
    'choose_sudoku_del': function(othis){
      $('#'+$('#layer_id').val()).val('')
      select_cell_num.pop(); 
    },
    //选择弹出层的数字，添充到选择区
    'choose_sudoku_close': function(othis){
      layer.closeAll(); // 关闭所有类型的层
    },
    //选择数独等级
    'sudoku_primary': function(othis){
      set_sudoku_level(1)
    },
    //选择数独等级
    'sudoku_intermediate': function(othis){
      set_sudoku_level(2)
    },
    //选择数独等级
    'sudoku_senior': function(othis){
      set_sudoku_level(3)
    },
    //选择数独等级
    'sudoku_hardcore': function(othis){
      set_sudoku_level(4)
    },
    'showlayer': function(othis){
      console.log(othis);
      console.log($(othis).attr("id"))
      //layer_id 是弹出层获取的上级（就是可操作对象）id
      content=get_layer_content($(othis).attr("id"));
      layer.tips(get_layer_content($(othis).attr("id")), this, {
        tips: [1, '#16b777'],
        time: 30000
      });
    }
  });
  //设置数独等级
  function set_sudoku_level(level){
    error_num=0;
    $('#sudoku_level').val(level);
    i=0;
    //点击更换数独难度等级样式
    $('#sudoku_level_btn button').each(function (){
      i++
      if(i==level){
        $(this).addClass('layui-btn-radius');
      }else{
        $(this).removeClass('layui-btn-radius');
      }
      
    })
    get_sudoku_info(level); 
  }

  //选中当前值，所有该值背景都色
  function select_cell(num,id){
    //自动检查，强调数字,强调区域
    console.log('select_cell')
    //如果选择自动检查
    if($("#auto_check").is(':checked')){
      for(i=1;i<82;i++){
          //区分类型（默认的ctype=1|用户添加的是ctype=2）
          let ctype=1;
          value=$('#cell_'+i).text();
          if(value==''){
              value=$('#ccontent_'+i).val();
              ctype=2;
          }
          //判断当前背景是否红色（错误），如果是红色就不操作
          color=rgb_to_hex($('#cell_'+i+' input[name=ccontent]').css('background-color'));
          if(color=='#ff0000'){ 
            continue;
          } 
      }
    }
    //强调数字
    if($("#auto_special").is(':checked')){
      for(i=1;i<82;i++){
        //区分类型（默认的ctype=1|用户添加的是ctype=2）.length>0
        let ctype=1;
        value=$('#cell_'+i).text();
        if(value==''){
            value=$('#ccontent_'+i).val();
            ctype=2;
        }
        if(ctype==1){
            $('#cell_'+i).css('background-color','#d2d2d2');
        }else{
          //$('#cell_'+i+' input[name=ccontent]').css('background-color','');
          source_color= rgb_to_hex($('#ccontent_'+i).css('background-color'));
          //console.log('-------i---:'+i+'--------value:'+value+'---------color:'+source_color)
          if(source_color!='#ff0000'){
            $('#ccontent_'+i).css('background-color','');
          }
          
        }
        if(value==num){
          if(ctype==1){
            $('#cell_'+i).css('background-color','#FFFF00');
          }else{
            $('#ccontent_'+i).css('background-color','#FFFF00');
          }
        }
      } 
    }
    //强调区域
    if($("#auto_area").is(':checked')){
      area=get_relate_data(id);
      console.log('----area start----');
      console.log(area)
      console.log('----area end----');
      for(i=0;i<area.length;i++){
        if($('#ccontent_'+area[i]).length>0){
          source_color= rgb_to_hex($('#ccontent_'+area[i]).css('background-color'));
          if(source_color!='#FFFF00'&&source_color!='#ff0000'){
            $('#ccontent_'+area[i]).css('background-color','#0000ff');
          }
          
        }else{
          source_color= rgb_to_hex($('#cell_'+area[i]).css('background-color'));
          if(source_color!='#FFFF00'&&source_color!='#ff0000'){
            $('#cell_'+area[i]).css('background-color','#0000ff');
          }
          $('#cell_'+area[i]).css('background-color','#0000ff');
        }
      }
    } 

  }


  //得到弹出层的内容（鼠标选择添充模式）
  function get_layer_content(id){
    html='<table id="sudoku_layer"><input id="layer_id" type="hidden" value="'+id+'">';
    for(i=1;i<4;i++){
      html+='<tr>';
      for(j=1;j<4;j++){
        html+='<td lay-on="choose_sudoku_num">'+((i-1)*3+j)+'</td>';
      }
      html+='</tr>'
    }
    html+='<tr><td colspan="2" lay-on="choose_sudoku_del">删除</td><td lay-on="choose_sudoku_close"><i class="layui-icon layui-icon-close"></i></td></tr></table>';
    return html
  }
  //rgb转16进制
  function rgb_to_hex(rgb){
    if(rgb==''||rgb==undefined){
      return undefined;
    }
    // 将RGB值转换为数组
    var rgbArray = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
    // 检查RGB值是否有效
    if (rgbArray) {
      // 将RGB值转换为十进制
      var r = parseInt(rgbArray[1], 10);
      var g = parseInt(rgbArray[2], 10);
      var b = parseInt(rgbArray[3], 10);
      // 将十进制转换为十六进制
      var hex = "#" + ((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1);
      return hex;
    } else {
      return null;
    }
  }
  //空格添满之后，判断是否全部正确
  function check_grid(){
    console.log('-----check_grid start-------')
    is_right=true;
    //检查列
    for(i=1;i<10;i++){
      var num='';
      if($('#ccontent_'+i).length>0){
        num=$('#ccontent_'+i).val();
      }else{
        num=$('#cell_'+i).text();
      }
      //set是去重的，如果有长度不为9说明有重复的
      const set_list = new Set();
      set_list.add(num)
      for(j=1;j<9;j++){
        index=j*9+i;
        if($('#ccontent_'+index).length>0){
          check_num=$('#ccontent_'+index).val();
        }else{
          check_num=$('#cell_'+index).text();
        }
        set_list.add(check_num)
      }
      if(set_list.size!=9){
        console.log(1)
        return false; 
      }
    }
    //检查行
    for(i=1;i<10;i++){
      var num='';
      col_index=(i-1)*9+1
      if($('#ccontent_'+col_index).length>0){
        num=$('#ccontent_'+col_index).val();
      }else{
        num=$('#cell_'+col_index).text();
      }
      //set是去重的，如果有长度不为9说明有重复的
      const set_list = new Set();
      set_list.add(num)
      for(j=1;j<9;j++){
        index=col_index+j;
        if($('#ccontent_'+index).length>0){
          check_num=$('#ccontent_'+index).val();
        }else{
          check_num=$('#cell_'+index).text();
        }
        set_list.add(check_num)
      }
      if(set_list.size!=9){
        console.log(2)
        return false; 
      } 
    }
    //检查宫
    block=get_block_list();
    for(i=0;i<9;i++){
      //set是去重的，如果有长度不为9说明有重复的
      const block_list = new Set();
      for(j=0;j<9;j++){
        if($('#ccontent_'+block[i][j]).length>0){
          check_num=$('#ccontent_'+block[i][j]).val();
        }else{
          check_num=$('#cell_'+block[i][j]).text();
        }
        block_list.add(check_num)
      }
      if(block_list.size!=9){
        console.log(block_list)
        console.log(3)
        return false; 
      } 
    }
    console.log('-----check_grid end-------')
    return is_right;
  }
/* 计时器 */
let sec = 0;
let min = 0;
let hour = 0;
 
function f() {
    /* 秒 */
    sec++;
    /* 分钟 */
    if (sec > 59) {
        min++;
        sec = 0;
    }
    /* 小时 */
    if (min > 59) {
        hour++;
        min = 0;
    }
    /* 写入 */
    let timer_str = doubleNum(hour) + ":" + doubleNum(min) + ":" + doubleNum(sec);
    $("#timer").html(timer_str);
};
/* 不足两位，前面补0 */
function doubleNum(n) {
    if (n < 10) {
        return "0" + n;
    } else {
        return n;
    }
};

			
  //得到宫的数字标签
  function get_block_list(){
    return [
      [1,2,3,10,11,12,19,20,21],
      [4,5,6,13,14,15,22,23,24],
      [7,8,9,16,17,18,25,26,27],
      [28,29,30,37,38,39,46,47,48],
      [31,32,33,40,41,42,49,50,51],
      [34,35,36,43,44,45,52,53,54],
      [55,56,57,64,65,66,73,74,75],
      [58,59,60,67,68,69,76,77,78],
      [61,62,63,70,71,72,79,80,81]
    ]
  }
  //检查相关数字（行，列，宫（Block））
  function get_relate_data(id){
    row=Math.ceil(id/9);
    col=(id%9)==0?9:id%9;
    block_list=get_block_list();
    row_arr=[]
    col_arr=[]
    block_arr=[];
    data=[];
    for(i=1;i<10;i++){
      console.log('---------------id:'+id);
      row_arr[i-1]=(row-1)*9+i;
      col_arr[i-1]=col+(i-1)*9;
      if(block_list[i-1].indexOf(parseInt(id))>-1){
        block_arr=block_list[i-1];
      }
    }
    //合并数组
    data = row_arr.concat(col_arr, block_arr);
    //数组去重
    list = [...new Set(data)];
    //删除当前数
    return list.filter(item => item != id)
  }
});
</script>
</body>
</html>
